#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Filename: buscar_ticket.py

##
# Módulos del sistema
try:
    import pygtk
    pygtk.require("2.0")
    import gtk
    import gtk.glade
except ImportError, error:
    print error
    print "Necesitas la librería gráficas gtk+pygtk"

# Utilidades
from datetime import datetime

##
# Módulos propios
try:
    from lib.database import Clasificacion, Estado, GrupoDeResolucion
    from lib.database import Empleado
    from lib.funciones_utiles import close
except ImportError, error:
    print error
    "Error en buscar_ticket"
try:
    from lib.config import WIDTH, HEIGHT
    from gui.msj_retroalimentacion import MensajeDeAdvertencia, MensajeDeError
    from gui.detalle_del_ticket import DetalleDelTicket
    from gui.derivar_ticket import DerivarTicket
    from gui.cerrar_ticket import CerrarTicket
    from lib.funciones_utiles import add_find_column
    from gui.configurar_reporte import ConfigurarReporte
except ImportError, error:
    print error
    print "Error en buscar_ticket.py"

class BuscarTicket:
    """Realiaza la actividad establecida en el CDU-02.

    Presenta la interfaz de los criterios de búsqueda de ticket.
    """
    def __init__(self, padre):
                # Establecemos el padre
        self.padre = padre
        self.hbox_118 = self.padre.wTree.get_widget("hbox118")
        self.vbox_15 = self.padre.wTree.get_widget("vbox15")
        # Creamos las cabecera de la lista de búsqueda
        self.tree_resultado = self.padre.wTree.get_widget("treeview1")
        self.armar_lista_resultado()
        self.lista_resultado = gtk.ListStore(str, str, str, str, str, str, str, str,
                str)
        self.tree_resultado.set_model(self.lista_resultado)
        # Widget de entrada
        # Entry
        self.legajo = self.padre.wTree.get_widget("entry34")
        self.apellido = self.padre.wTree.get_widget("entry35")
        self.nombre = self.padre.wTree.get_widget("entry36")
        self.nro_ticket = self.padre.wTree.get_widget("entry56")
        # Combobox
        self.clasificacion = self.padre.wTree.get_widget("combobox3")
        self.clasificacion.set_model(gtk.ListStore(str))
        self.estado = self.padre.wTree.get_widget("combobox11")
        self.estado.set_model(gtk.ListStore(str))
        self.ultimo_grupo = self.padre.wTree.get_widget("combobox14")
        self.ultimo_grupo.set_model(gtk.ListStore(str))
        self.lista_grupos = {'Todos': None}
        self.lista_clasificaciones = {'Todas': None}
        self.lista_estados = {'Todos': None}
        self.armar_combos()
        # SpinButton
        # Fecha de apertura
        self.fa_desde_dia = self.padre.wTree.get_widget("spinbutton44")
        self.fa_desde_mes = self.padre.wTree.get_widget("spinbutton45")
        self.fa_desde_anio = self.padre.wTree.get_widget("spinbutton46")
        self.fa_hasta_dia = self.padre.wTree.get_widget("spinbutton47")
        self.fa_hasta_mes = self.padre.wTree.get_widget("spinbutton48")
        self.fa_hasta_anio = self.padre.wTree.get_widget("spinbutton49")
        # Fecha de último cambio
        self.fu_desde_dia = self.padre.wTree.get_widget("spinbutton62")
        self.fu_desde_mes = self.padre.wTree.get_widget("spinbutton63")
        self.fu_desde_anio = self.padre.wTree.get_widget("spinbutton64")
        self.fu_hasta_dia = self.padre.wTree.get_widget("spinbutton65")
        self.fu_hasta_mes = self.padre.wTree.get_widget("spinbutton66")
        self.fu_hasta_anio = self.padre.wTree.get_widget("spinbutton67")
        self.establecer_limite_fecha()
        self.empleado = None
        self.conect_entry_enter()
        self.lista_ticket=[]
        self.bandera = True
    
    def imprimir_consola(self):
        print "Anda"
    
    def establecer_limite_fecha(self):
        """Pone la fecha tope como la fecha actual"""
        fecha_actual = datetime.now()
        fechas_hasta = (float(fecha_actual.day),
                float(fecha_actual.month),
                float(fecha_actual.year))
        # Fecha de apertura desde y Fecha de ultimo cambio desde
        lista_variables_desde = (
                (self.fa_desde_dia, self.fa_desde_mes, self.fa_desde_anio),
                (self.fu_desde_dia, self.fu_desde_mes, self.fu_desde_anio))
        for valor in lista_variables_desde:
            valor[0].set_range(1.0, 31)
            valor[1].set_range(1.0, 12)
            valor[2].set_range(1990.0, fechas_hasta[2])
        
        # Fecha de apertura hasta y Fecha de ultimo cambio hasta
        lista_variables_hasta = (
                (self.fa_hasta_dia, self.fa_hasta_mes, self.fa_hasta_anio),
                (self.fu_hasta_dia, self.fu_hasta_mes, self.fu_hasta_anio))
        for valor in lista_variables_hasta:
            # Rango de fechas
            valor[0].set_range(1.0, fechas_hasta[0])
            valor[1].set_range(1.0, fechas_hasta[1])
            valor[2].set_range(1990.0, fechas_hasta[2])
            # Establecemos el valor
            valor[0].set_value(fechas_hasta[0])
            valor[1].set_value(fechas_hasta[1])
            valor[2].set_value(fechas_hasta[2])

    def armar_lista_resultado(self):
        titulos = ["Nro", "Legajo", "Fecha\napertura", "Hora\napertura",
                "Usuario que\ncreo el ticket", "Clasificacion\nactual",
                "Estado\nactual", "Fecha último\ncambio estado",
                "G.R.\nactual asignado"]
        for pos,titulo in enumerate(titulos):
            add_find_column(titulo, pos, self.tree_resultado)

    def conect_entry_enter(self):
        """Permite generar the activate signal para los widget"""
        def grab_focus(widget, other):
            other.grab_focus()
            self.completar_campos()

        def groups(lista, n, step=1):
            for index in xrange(0, len(lista)-(n-1), step):
                yield lista[index:index+n]

        path =(self.legajo, self.apellido)
        for from0, to in groups(path, 2):
            from0.connect("activate", grab_focus, to)

    def completar_campos(self):
        """Completará los campos de apellido y nombre.

        Busca en la base de datos el nombre y apellido del Empleado con legajo
        "nro_legajo".

        Keyword arguments:
        None
        """
        nro_legajo = self.legajo.get_text()
        if nro_legajo != '':
            # Levantar el apellido y nombre con este legajo
            consulta = Empleado.selectBy(legajo = nro_legajo)
            try:
                empleado = consulta[0]
                self.apellido.set_text(empleado.apellido)
                self.nombre.set_text(empleado.nombre)
                self.empleado = empleado
                self.nro_ticket.grab_focus()
            except IndexError, error:
                print error
                msj = "Nro. de legajo inexistente en el Sistema de Personal."
                print msj
                msj_error = MensajeDeError(msj, self.padre.window)
                msj_error.run()
                self.legajo.set_text('')
                self.legajo.grab_focus()


    def armar_combos(self):
        """Llenará con los datos correspondientes los comboboxentry.

        Buscará en la base de dato los grupos de resolucion, las clasificaciones
        y los estados activos.

        Keyword arguments:
        """

        self.ultimo_grupo.append_text("Todos")
        self.clasificacion.append_text("Todas")
        # Llenamos el de los grupos
        consulta_grupos = GrupoDeResolucion.select()
        for grupo in consulta_grupos:
            self.lista_grupos[grupo.nombre] = grupo
            self.ultimo_grupo.append_text(grupo.nombre)
        self.ultimo_grupo.set_active(0)
        # Llenamos el de las clasificaciones
        consulta_clasificacion = Clasificacion.select()
        for clasificacion in consulta_clasificacion:
            self.lista_clasificaciones[clasificacion.nombre] = clasificacion
            self.clasificacion.append_text(clasificacion.nombre)
        self.clasificacion.set_active(0)
        # Llenamos el de los estados
        consulta_estado = Estado.select()
        for estado in consulta_estado:
            self.lista_estados[estado.nombre] = estado
            self.estado.append_text(estado.nombre)
        self.estado.append_text("Todos")
        self.estado.set_active(0)


    def obtener_fechas_desde_los_spin(self):
        """Arma objetos datetime con los datos obtenidos desde los spin."""

        fecha_actual = datetime.now()
        self.fecha_apertura_desde = datetime(
                self.fa_desde_anio.get_value_as_int(),
                self.fa_desde_mes.get_value_as_int(),
                self.fa_desde_dia.get_value_as_int())
        self.fecha_apertura_hasta = datetime(
                self.fa_hasta_anio.get_value_as_int(),
                self.fa_hasta_mes.get_value_as_int(),
                self.fa_hasta_dia.get_value_as_int())
        self.fecha_ultimo_cambio_desde = datetime(
                self.fu_desde_anio.get_value_as_int(),
                self.fu_desde_mes.get_value_as_int(),
                self.fu_desde_dia.get_value_as_int())
        self.fecha_ultimo_cambio_hasta = datetime(
                self.fu_hasta_anio.get_value_as_int(),
                self.fu_hasta_mes.get_value_as_int(),
                self.fu_hasta_dia.get_value_as_int())

    def buscar_ticket(self, widget=None):
        self.obtener_fechas_desde_los_spin()
        nro_ticket = 0
        if self.nro_ticket.get_text():
            nro_ticket = int(self.nro_ticket.get_text())
        self.lista_ticket = self.padre.mesa_de_ayuda.buscar_ticket(
                self.empleado,
                self.tomar_valor_combo(1),#grupo
                self.tomar_valor_combo(2),#clasificacion
                self.tomar_valor_combo(3),#estado
                nro_ticket,
                self.fecha_apertura_desde,
                self.fecha_apertura_hasta,
                self.fecha_ultimo_cambio_desde,
                self.fecha_ultimo_cambio_hasta)
        self.mostrar_resultados()

    def mostrar_resultados(self, widget=None):
        """Llamará a la funcion buscarTicket de self.padre

        Se mostrarán todos los ticket que halla encontrado la funcion.
        """
        if self.lista_ticket:
            self.lista_resultado.clear()
            self.hbox_118.hide()
            self.vbox_15.show()
            self.datos_comunes()
            # Mostramos los ticket en la lista de resultado
            for ticket in self.lista_ticket:
                lista = [ticket.numero_ticket,
                        ticket.empleado.legajo,
                        ticket.fecha_creacion.strftime("%d-%m-%Y"),
                        ticket.fecha_creacion.strftime("%H:%M"),
                        ticket.usuario_creacion.u_legajo,
                        ticket.clasificacion_actual.nombre,
                        ticket.estado_actual.nombre,
                        ticket.historial_de_estado[-1].fecha.strftime("%d-%m-%Y"),
                        ticket.grupo_de_resolucion.nombre]
                self.lista_resultado.append(lista)
                if self.bandera:
                    self.padre.mesa_de_ayuda.tickets[ticket.numero_ticket] = ticket#guardamos en memoria
            self.bandera = False
        else:
            error = "No hay ticket que cumplan con esos requisitos."
            print error
            msj_error = MensajeDeError(error, self.padre.window)
            msj_error.run()

    def datos_comunes(self):
        """Muestro la informacion estatica en la parte superior."""
        # Cliente
        if self.empleado:
            self.padre.wTree.get_widget("label757").set_text(self.empleado.legajo)
            self.padre.wTree.get_widget("label758").set_text(self.empleado.apellido)
            self.padre.wTree.get_widget("label759").set_text(self.empleado.nombre)
        else:
            self.padre.wTree.get_widget("frame192").hide()
        # Ticket
        if self.nro_ticket.get_text():
            self.padre.wTree.get_widget("label771").set_text(self.nro_ticket.get_text())
        else:
            self.padre.wTree.get_widget("label771").set_text("Todos")
        # Clasificacion del ticket
        if self.tomar_valor_combo(2) == "Todas":
            self.padre.wTree.get_widget("label772").set_text("Todas")
        else:
            self.padre.wTree.get_widget("label772").set_text(self.tomar_valor_combo(2).nombre)
        # Estado del ticket
        if self.tomar_valor_combo(3) == None:
            self.padre.wTree.get_widget("label773").set_text("Todos")
        else:
            self.padre.wTree.get_widget("label773").set_text(self.tomar_valor_combo(3).nombre)
        # Fechas
        if self.fecha_apertura_desde == self.fecha_apertura_hasta:
            self.padre.wTree.get_widget("label763").set_text("----")
        else:
            self.padre.wTree.get_widget("label763").set_text(
                self.fecha_apertura_desde.strftime("%d-%m-%Y") + ' ' +
                self.fecha_apertura_hasta.strftime("%d-%m-%Y")
                )
        if self.fecha_ultimo_cambio_desde == self.fecha_ultimo_cambio_hasta:
            self.padre.wTree.get_widget("label764").set_text("----")
        else:
            self.padre.wTree.get_widget("label764").set_text(
                self.fecha_ultimo_cambio_desde.strftime("%d-%m-%Y") + ' ' +
                self.fecha_ultimo_cambio_hasta.strftime("%d-%m-%Y")
                )
        # Grupos de resolucion
        if self.tomar_valor_combo(1) == "Todos":
            self.padre.wTree.get_widget("label766").set_text("Todos")
        else:
            self.padre.wTree.get_widget("label766").set_text(self.tomar_valor_combo(1).nombre)

    def tomar_valor_combo(self, combo):
        """Devuelve el valor del combo requerido.
        Retorna el valor del diccionario 'combo' que tenga como llave
        el valor de seleccion del 'combo'.
        Keyword arguments:
        combo -- type int
                    1 - Grupo de resolucion
                    2 - Clasificacion
                    3 - Estado
        """
        diccionario = {1: (self.ultimo_grupo, self.lista_grupos),
                2: (self.clasificacion, self.lista_clasificaciones),
                3: (self.estado, self.lista_estados)}

        model = diccionario[combo][0].get_model()
        index = diccionario[combo][0].get_active()
        print "Tomar valor: %s" % diccionario[combo][0].get_active_text()
        #import pdb
        #pdb.set_trace()
        if index and combo == 1:
            return diccionario[combo][1][model[index][0]]
        elif index and combo == 2:
            return diccionario[combo][1][model[index][0]]
        elif combo==1:
            return "Todos"
        elif combo==2:
            return "Todas"
        else:
            #pdb.set_trace()
            return diccionario[combo][1][model[index][0]]

    def derivar_ticket(self, widget=None):
        """Invoca a derivar ticket """
        model, path = self.tree_resultado.get_selection().get_selected_rows()
        if path:
            pos, = path[0]
            estado = self.lista_ticket[pos].estado_actual.nombre
            if (estado == 'Abierto en Mesa de Ayuda' or
                    estado == 'No Solucionado'):
                self.derivar = DerivarTicket(self, self.lista_ticket[pos])
            else:
                error = ("Para derivar un ticket el estado tiene que ser:",
                        "\t- Abierto en Mesa de Ayuda",
                        "\t- No Solucionado")
                msj = MensajeDeError("\n".join(error), self.padre.window)
                msj.run()
        else:
             error = "Para ver el detalle del ticket debe seleccionarlo"
             msj = MensajeDeError(error, self.padre.window)
             msj.run()

    def cerrar_ticket(self, widget=None):
        """Invoca a cerrar ticket"""
        model, path = self.tree_resultado.get_selection().get_selected_rows()
        if path:
            pos, = path[0]
            # Para invocar a Cerrar Ticket ademas de estar en estado
            # Solucionado a la espera OK, todas las intervenciones tienen que
            # estar en estado 'Resuelta'
            bandera = self.comprobar_estado_cierre(self.lista_ticket[pos])
            if bandera:
                self.cerrar = CerrarTicket(self, self.lista_ticket[pos])
            else:
                error = ("Para cerrar el ticket, su estado debe ser:",
                        "\t- Solucionado a la espera OK y",
                        "Todas sus intervenciones tienen que estar en estado:",
                        "\t- Resuelta o Finalizada")
                msj = MensajeDeError("\n".join(error), self.padre.window)
                msj.run()
        else:
             error = "Para cerrar el ticket debe seleccionarlo"
             msj = MensajeDeError(error, self.padre.window)
             msj.run()
    
    def comprobar_estado_cierre(self, ticket):
        """Se fija si el ticket es apto para ser cerrado"""
        bandera = True
        if ticket.estado_actual.nombre == "Solucionado a la espera OK":
            finalizada = 0
            for intervencion in ticket.intervenciones:
                if (intervencion.estado == 'Resuelta' or
                        intervencion.estado == 'Finalizada'):
                    if intervencion.estado == 'Finalizada':
                        finalizada+=1
                    pass
                else:
                    return False
            if finalizada == len(ticket.intervenciones):
                return False
        else:
            bandera = False
        return bandera


    def close(self, widget=None):
        close(self.padre.window)

    def aceptar(self, widget=None):
        """
        Cierra la ventana de buscar ticket.
        """
        self.padre.wTree.get_widget("hbox118").show()
        self.padre.wTree.get_widget("vbox15").hide()
        self.lista_resultado.clear()
        self.limpiar_campos(None)

    def limpiar_campos(self, widget=None):
        """Limpiará los campos.

        Recorrerá todos los widget de 'criterios de busqueda' y los pondra en
        su estado de default.
        """
        self.lista_resultado.clear()
        lista_entry = (self.legajo, self.nombre, self.apellido,
                self.nro_ticket)
        lista_combo = (self.clasificacion, self.ultimo_grupo, self.estado)
        #Limpiamos
        for entry in lista_entry:
            entry.set_text('')
        #for combo in lista_combo:
        #    combo.set_active(0)
        self.cleane_spin()

    def cleane_spin(self):
        """Pone los spin button en sus valores de default."""
        lista_spin_1 = (self.fa_desde_dia, self.fa_desde_mes,
                self.fu_desde_dia, self.fu_desde_mes)
        lista_spin_1999 = (self.fa_desde_anio, self.fu_desde_anio)
        for spin in lista_spin_1:
            spin.set_value(1)
        for spin in lista_spin_1999:
            spin.set_value(1999)
        self.establecer_limite_fecha()

    def detalle_del_ticket(self, widget=None):
        """
            Creamos una instancia de dialog_detalle_ticket
        """
        model, path = self.tree_resultado.get_selection().get_selected_rows()
        if path:
            pos, = path[0]
            self.detalle_ticket = DetalleDelTicket(self.padre.window, self.lista_ticket[pos])
        else:
             error = "Para ver el detalle del ticket debe seleccionarlo"
             msj = MensajeDeError(error, self.padre.window)
             msj.run()

    def config_report(self, widget=None):
        print "Config Report"
        self.configurar_reporte = ConfigurarReporte(self)
